package com.imitationsql.web.api;

import cn.hutool.core.bean.BeanUtil;
import com.imitationsql.web.annotation.Column;
import com.imitationsql.web.annotation.LabelValue;
import com.imitationsql.web.annotation.Power;
import com.imitationsql.web.config.EnableAutoApi;
import com.imitationsql.web.domain.*;
import com.imitationsql.web.service.JdbcService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>Description: some description </p>
 *
 * @author : xiaodong.yang
 * @date : 2024/3/15 14:09
 */
public class BaseApi<T extends BaseEntity> {

    private final JdbcService jdbcService;

    private final Class<T> entityClass;

    public BaseApi(JdbcService jdbcService, Class<T> entityClass) {
        this.jdbcService = jdbcService;
        this.entityClass = entityClass;
    }

    /**
     * 查询详情
     *
     * @param id
     * @return
     */
    @ResponseBody
    public CommonResult<T> detail(@PathVariable(name = "id") Serializable id) {
        CommonResult<T> result = new CommonResult<>();
        result.setData(jdbcService.detail(this.entityClass, id));
        return result;
    }

    /**
     * 分页查询
     *
     * @param page
     * @return
     */
    @ResponseBody
    public CommonResult<Page<T>> pageQuery(@RequestBody QueryPage page) {
        CommonResult<Page<T>> result = new CommonResult<>();
        result.setData(jdbcService.pageQuery(this.entityClass, BeanUtil.toBean(page, QueryPage.class)));
        return result;
    }

    /**
     * 列表查询
     *
     * @param entity
     * @return
     */
    @ResponseBody
    public CommonResult<List<T>> list(@RequestBody Object entity) {
        CommonResult<List<T>> result = new CommonResult<>();
        result.setData(jdbcService.list(this.entityClass, BeanUtil.toBean(entity, this.entityClass)));
        return result;
    }

    /**
     * 新增
     *
     * @param entity
     * @return
     */
    @ResponseBody
    public CommonResult<T> insert(@RequestBody Object entity) {
        CommonResult<T> result = new CommonResult<>();
        result.setData(jdbcService.insert(BeanUtil.toBean(entity, this.entityClass)));
        return result;
    }

    /**
     * 更新
     *
     * @param entity
     * @return
     */
    @ResponseBody
    public CommonResult<Boolean> update(@RequestBody Object entity) {
        CommonResult<Boolean> result = new CommonResult<>();
        result.setData(jdbcService.update(BeanUtil.toBean(entity, this.entityClass)));
        return result;
    }

    /**
     * 逻辑删除
     *
     * @param id
     * @return
     */
    @ResponseBody
    public CommonResult<Boolean> delete(@RequestParam(name = "id") Serializable id) {
        CommonResult<Boolean> result = new CommonResult<>();
        result.setData(jdbcService.delete(entityClass, id));
        return result;
    }

    /**
     * 逻辑批量删除
     *
     * @param ids
     * @return
     */
    @ResponseBody
    public CommonResult<Boolean> batchDelete(@RequestParam(name = "ids") String ids) {
        CommonResult<Boolean> result = new CommonResult<>();
        result.setData(jdbcService.batchDelete(entityClass, Arrays.asList(ids.split(","))));
        return result;
    }

    /**
     * 物理删除
     *
     * @param id
     * @return
     */
    @ResponseBody
    public CommonResult<Boolean> physicalDelete(@RequestParam(name = "id") Serializable id) {
        CommonResult<Boolean> result = new CommonResult<>();
        result.setData(jdbcService.physicalDelete(entityClass, id));
        return result;
    }

    /**
     * 物理批量删除
     *
     * @param ids
     * @return
     */
    @ResponseBody
    public CommonResult<Boolean> physicalBatchDelete(@RequestParam(name = "ids") List<Serializable> ids) {
        CommonResult<Boolean> result = new CommonResult<>();
        result.setData(jdbcService.physicalBatchDelete(entityClass, ids));
        return result;
    }

    /**
     * 物理批量删除
     *
     * @return
     */
    @ResponseBody
    public CommonResult<FormMetaData> formStruct() {
        CommonResult<FormMetaData> result = new CommonResult<>();
        FormMetaData formMetaData = new FormMetaData(new ArrayList<>(), new ArrayList<>());
        result.setData(formMetaData);
        List<String> powers = formMetaData.getPowers();
        Power power = entityClass.getAnnotation(EnableAutoApi.class).power();
        if (power.add()) {
            powers.add("add");
        }
        if (power.edit()) {
            powers.add("edit");
        }
        if (power.delete()) {
            powers.add("delete");
        }
        if (power.batchDelete()) {
            powers.add("batchDelete");
        }
        if (power.physicalBatchDelete()) {
            powers.add("physicalBatchDelete");
        }
        if (power.detail()) {
            powers.add("detail");
        }
        if (power.exportData()) {
            powers.add("exportData");
        }
        if (power.importData()) {
            powers.add("importData");
        }
        Field[] fields = entityClass.getDeclaredFields();
        for (Field field : fields) {
            Column column = field.getAnnotation(Column.class);
            if (null == column) {
                continue;
            }
            ColumnMetaData columnMetaData = new ColumnMetaData();
            columnMetaData.setName(field.getName());
            columnMetaData.setEnableEdit(column.enableEdit());
            LabelValue[] mulitValue = column.mulitValue();
            if (mulitValue.length > 0) {
                List<LabelValueMetaData> labelValues = new ArrayList<>();
                for (LabelValue labelValue : mulitValue) {
                    LabelValueMetaData labelValueMetaData = new LabelValueMetaData(labelValue.label(), labelValue.value());
                    labelValues.add(labelValueMetaData);
                }
                columnMetaData.setLabelValues(labelValues);
            }
            columnMetaData.setType(column.type().getType());
            columnMetaData.setQueryParam(column.isQueryParam());
            columnMetaData.setQueryType(column.queryType().getType());
            columnMetaData.setValidate(column.isValidate());
            columnMetaData.setValidateReg(column.validateReg());
            columnMetaData.setDynamicLoading(column.isDynamicLoading());
            if (column.isDynamicLoading()) {
                DynamicDataMeta dynamicDataMeta = new DynamicDataMeta(column.dynamicData().url(), column.dynamicData().method(), column.dynamicData().dataStructure());
                columnMetaData.setDynamicData(dynamicDataMeta);
            }
            formMetaData.getColumnMetaDataList().add(columnMetaData);
        }
        return result;
    }
}
